package com.wksc.framework.impexp.util;

import java.io.File;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 读取配置文件类
 * 
 * @author QinJinxue
 * @daJan 11, 2011
 * @since 1.0
 */
public class Cfg {
	private static Cfg instance = null;
	private static Document config = null;
	private static Element root = null;
	public static String MODULE_MARK = null;
	/** 系统根路径 */
	public static String SYS_PATH = SysParam.getSysPath();
	/**
	 * @Fields CFG_PATH : 配置的
	 */
	private static String cfgPath = null;

	//	static {
	//		String path = Thread.currentThread().getContextClassLoader()
	//				.getResource("").getPath();
	//		path = replaceSlash(path);
	//		if (path.charAt(0) == '/') {
	//			path = path.substring(1);
	//		}
	//		if (!System.getProperty("os.name").toUpperCase().contains("WINDOWS")) {
	//			path = "/" + path; //切换成绝对路径
	//		}
	//		path += "/../../conf/server.xml";
	//		path = replaceSlash(path);
	//		
	//	}

	/**
	 * 功能描述: checkeStyle
	 * 
	 * @Title: replaceSlash
	 * @Description: 将/ab\\/c\\d/替换成/ab/c/d
	 * @creator pengqianyu
	 * @param str
	 *            待替换字符串
	 * @return String 替换后字符串
	 */
	private static String replaceSlash(String str) {
		str = str.replaceAll("\\\\", "/");
		str = str.replaceAll("/+", "/");
		return str;
	}

	private Cfg() {
	}

	public static synchronized Cfg getInstance() {
		if (instance == null) {
			instance = new Cfg();
			load();
			setCfgPath(); //初始化导入导出文件服务器存放位置
		}
		return instance;
	}

	public String getCfgPath() { //这个必须是非静态类,保证实例化Cfg时先加载xml,再通过xml设置cfgPath的值
		if (cfgPath == null) {
			Cfg.getInstance(); //初始化,如果这样都还为空,那.............不能使用return Cfg.getInstance().getCfgPath()是因为一旦真的有那种情况,会造成无线递归
		}
		return cfgPath;
	}

	public static void setCfgPath(String cfgPath) {
		//		if (Cfg.cfgPath != null) { //是否要做成不可改变/?
		//			return;
		//		}
		//这个地方实际上会造成一种不一致,如果sys_path中包含有${XXX}并且当作参数传入,则会被翻译,但是如果参数为空,则不会被翻译
		if (cfgPath == null) {
			Cfg.cfgPath = Cfg.SYS_PATH;
			return;
		}
		cfgPath = cfgPath.trim();
		if (cfgPath.length() == 0) {
			Cfg.cfgPath = Cfg.SYS_PATH;
			return;
		}
		Cfg.cfgPath = parsePath(cfgPath); //使用环境变量转换,是否有必要/?
	}

	/**
	 * 功能描述: checkeStyle
	 * 
	 * @Title: setCfgPath
	 * @Description: 设置cfgPath,读取配置文件的方式,如果配置文件中没有配置信息,则使用SYS_PATH
	 * @creator Owner
	 */
	public static void setCfgPath() {
		//		if (Cfg.cfgPath != null) { //是否要做成不可改变/?
		//			return;
		//		}
		setCfgPath(Cfg.getInstance().getString("filesSaveDir", SYS_PATH)); 
	}

	/**
	 * 功能描述: checkeStyle
	 * 
	 * @Title: parsePath
	 * @Description: 查找${},取出其对应的环境变量值
	 * @creator Owner
	 * @param path
	 *            存在${}的路径
	 * @return String 翻译后的路径
	 */
	private static String parsePath(String path) {
		int beg = path.indexOf("${");
		if (beg == -1) {
			return path;
		}
		int end = path.indexOf("}", beg + 2);
		if (end == -1) {
			return path;
		}
		String property = path.substring(beg + 2, end);
		property = property.trim();
		if (property.length() == 0) {
			return path;
		}
		String val = System.getProperty(property);
		if (val == null) {
			val = System.getenv(property);
			if (val == null) {
				return path;
			}
		}
		return parsePath(path.substring(0, beg) + val
				+ path.substring(end + 1, path.length()));
	}

	/**
	 * 加载配置文件
	 * 
	 * @author QinJinxue
	 */
	private static void load() {
		SAXReader reader = new SAXReader();
		try {
			// 2011-11-13 zhangyan add 从环境变量ANTI_SAM中读取配置文件的位置.
			String path = instance.getEnv();
			if (path == null || path.length() == 0) { // 未配置环境变量
				path = new StringBuilder().append(SYS_PATH).append(
						"/WEB-INF/classes/config/impExp.xml").toString();
			} else { // 配置了环境变量ANTI_SAM
				path = new StringBuilder(path).append("/impExp.xml").toString();
			}
			config = reader.read(new File(path));
			root = config.getRootElement();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 方法描述：获取环境变量ANTI_SAM的值：配置文件impExp.xml的路径 2011-11-13 zhangyan add
	 * 
	 * @creator 张艳
	 * @return 配置文件impExp.xml的路径
	 */
	private String getEnv() {
		String envPath = System.getenv(ClassFactory.getOutInterface().getEnv());
		if (envPath != null && envPath.trim().length() > 0) {
			if (envPath.endsWith("/") || envPath.endsWith("\\")) {
				envPath = envPath.substring(0, envPath.length() - 1);
			}
		} else {
			envPath = "";
		}
		return envPath;
	}

	/**
	 * 获取节点的内容
	 * 
	 * @author QinJinxue
	 * @param nodeName
	 * @return
	 */
	private String getText(String nodeName) {
		String result = null;
		for (Iterator<?> i = root.elementIterator(nodeName); i.hasNext();) {
			Element elm = (Element) i.next();
			result = elm.getText().trim();
		}
		return result;
	}

	/**
	 * 获取字符串内容
	 * 
	 * @author QinJinxue
	 * @param nodeName
	 * @param def
	 * @return
	 */
	public String getString(String nodeName, String def) {
		String str = null;
		try {
			str = this.getText(nodeName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str == null ? def : str;
	}

	/**
	 * 获取字符串内容
	 * 
	 * @author QinJinxue
	 * @param nodeName
	 * @param def
	 * @return
	 */
	public int getInt(String nodeName, int def) {
		Integer integer = null;
		try {
			integer = Integer.valueOf(this.getText(nodeName));
		} catch (NumberFormatException e) {
			return def;
		}
		return integer == null ? def : integer;
	}

	/**
	 * 方法描述：从配置文件获取布尔值
	 * 
	 * @creator wanglei
	 * @param nodeName
	 *            节点名称
	 * @param def
	 *            默认值
	 * @return
	 */
	public boolean getBoolean(String nodeName, boolean def) {
		boolean result = false;
		try {
			result = Boolean.valueOf(this.getText(nodeName));
		} catch (Exception e) {
			return def;
		}
		return result;
	}
}
